/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package GestureRecognition;

import com.googlecode.javacv.cpp.opencv_core.CvPoint;
import com.googlecode.javacv.cpp.opencv_core.CvSeq;
import coordinates.ConvexHull;

/**
 *
 * @author HOME
 */
public class Gestures_single_camera {

    private ConvexHull ch = new ConvexHull();
    static int frameCount = 0;
    private CvPoint preLargestTip;
    private CvPoint preSecondLargestTip;
    private CvPoint LargestTip;
    private CvPoint SecondLargestTip;
    final int MIN_ROTATE = 10;
    final int MAX_SCROLL = 5;
    final int MAX_FRAME_COUNT = 3;

    public void identifyGestureType(CvSeq largestCont, CvSeq secondLargestCont, boolean isConsecutive) {

        if (!isConsecutive) {
            frameCount = 0;
            return;

        } else {
            if (frameCount == 0) {
                preLargestTip = ch.getFingerTip(largestCont);
                preSecondLargestTip = ch.getFingerTip(secondLargestCont);
                frameCount++;
                return;

            } else if (frameCount < MAX_FRAME_COUNT) {
                frameCount++;
                return;

            } else {
                frameCount = 0;
                LargestTip = ch.getFingerTip(largestCont);
                SecondLargestTip = ch.getFingerTip(secondLargestCont);

                int diffLargeX = LargestTip.x() - preLargestTip.x();
                int diffLargeY = LargestTip.y() - preLargestTip.y();
                int diffSecondLargeX = SecondLargestTip.x() - preSecondLargestTip.x();
                int diffSecondLargeY = SecondLargestTip.y() - preSecondLargestTip.y();


                if ((Math.abs(diffLargeY)) > MIN_ROTATE && (Math.abs(diffSecondLargeY)) > MIN_ROTATE) { // Rotate starting from horizontal
                    int dir = (int) Math.copySign(1, diffLargeY);
                    // +1: anticlockwise ****should be the least point in x
                    // -1: Clockwise
                    
                    double angle1 = Math.atan2(LargestTip.y() - SecondLargestTip.y(), LargestTip.x() - SecondLargestTip.x());
                    double angle2 = Math.atan2(preLargestTip.y() - preSecondLargestTip.y(), preLargestTip.x() - preSecondLargestTip.x());
                    double angle = angle1 - angle2;
                    rotate(dir, angle);

                } else if ((diffLargeX - diffSecondLargeX) < MAX_SCROLL) { // Horizontal Scroll
                    int dir = (int) Math.copySign(1, diffLargeX);
                    // +1: Right Side
                    // -1: Left Side
            
                    scroll(dir);

                } else { // Zoom
                    int magZoom = (Math.abs(LargestTip.x() - SecondLargestTip.x()) - Math.abs(preLargestTip.x() - preSecondLargestTip.x())) / 2;
                    int dir = (int) Math.copySign(1, magZoom);
                    // +1: Zoom Out
                    // -1: Zoom In
                    zoom(dir, Math.abs(magZoom));

                }
            }
        }
    }

    public void rotate(int dir, double angle) {
        System.out.println("Rotate");
        System.out.println("Direction= " + dir);
        System.out.println("Angle= " + angle);
    }

    public void scroll(int dir) {
        System.out.println("Scroll");
        System.out.println("Direction= " + dir);
    }

    public void zoom(int dir, int magnitude) {
        System.out.println("Zoom");
        System.out.println("Direction= " + dir);
        System.out.println("Magnitude= " + magnitude);
    }
}
